#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>

void PrintModules(DWORD processID) {
	printf("\n\tModules:\n");

	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
	if (hProcess == NULL) {
		return;
	}

	HMODULE hMods[1024];
	DWORD cbNeeded;
	if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
		for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
			TCHAR szModName[MAX_PATH];

			if (GetModuleFileNameEx( hProcess, hMods[i], szModName,
				sizeof(szModName) / sizeof(TCHAR))) {
				printf("\t%s (0x%08X)\n", szModName, hMods[i]);
			}
		}
	}

	CloseHandle(hProcess);
}

void PrintMemoryInfo(DWORD processID) {
	printf("\n\tMemory usage:\n");

    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (hProcess == NULL) {
        return;
	}

	PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
        printf("\tWorkingSetSize: %d\n", pmc.WorkingSetSize);
		printf("\tPeakWorkingSetSize: %d\n", pmc.PeakWorkingSetSize);
        printf("\tPagefileUsage: %d\n", pmc.PagefileUsage); 
        printf("\tPeakPagefileUsage: %d\n", pmc.PeakPagefileUsage);
    }

    CloseHandle( hProcess );
}

void printProcessExecutableName(DWORD processID) {
	printf("\n\tExecutable name:\n");

	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (hProcess == NULL) {
        return;
	}

	DWORD dwFlags = PROCESS_NAME_NATIVE;
	LPSTR lpExeName = new char[1024];
	PDWORD lpdwSize = new DWORD;
	*lpdwSize = 1024;
	QueryFullProcessImageName(hProcess, dwFlags, lpExeName, lpdwSize);
	printf("\t%s\n", lpExeName);

    CloseHandle(hProcess);
}

int main() {
	DWORD aProcesses[1024]; 
	DWORD cbNeeded; 

	if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
		return 1;
	}

	DWORD cProcesses = cbNeeded / sizeof(DWORD);

	for (unsigned int i = 0; i < cProcesses; i++) {
		printf("\nProcess ID: %u\n", aProcesses[i]);
		printProcessExecutableName(aProcesses[i]);
		PrintModules(aProcesses[i]);
		PrintMemoryInfo(aProcesses[i]);
	}

	getchar();

	return 0;
}